package com.xms.security.service.dataauth;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xms.datacore.PrimaryKeyProviderFunction;
import com.xms.security.entity.RoleObjectAccess;
import com.xms.security.identity.ICurrentUser;
import com.xms.utils.CollectionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * ObjectAuthorizationFilter
 * </p>
 *
 * @author migo
 * @since 2021/10/20
 */
@Service
public class ObjectAuthorizationFilter implements IObjectAuthorizationFilter {
    private IRoleObjectAccessService _roleObjectAccessService;
    private ICurrentUser _currentUser;

    @Autowired
    public void ObjectAuthorizationFilter(IRoleObjectAccessService roleObjectAccessService,
                                          ICurrentUser currentUser) {
        _roleObjectAccessService = roleObjectAccessService;
        _currentUser = currentUser;
    }

    @Override
    public <T> void filter(int typeCode, Collection<T> data, PrimaryKeyProviderFunction<T> primaryKeyProviderFunction) {
        if (_currentUser.isAdministrator())
            return;
        //PrimaryKeyProviderFunction<RoleObjectAccess> function = (f)->{return f.getObjectid();};
        List<UUID> userRoles = _currentUser.getRoles();
        if (CollectionUtil.notEmpty(userRoles)) {
            List<UUID> objectId = data.stream().map(x -> primaryKeyProviderFunction.getPrimaryKey(x)).collect(Collectors.toList());
            List<RoleObjectAccess> roaList = _roleObjectAccessService.list(new LambdaQueryWrapper<RoleObjectAccess>()
                    .in(RoleObjectAccess::getObjectid, objectId)
                    .in(RoleObjectAccess::getRoleid, userRoles)
                    .eq(RoleObjectAccess::getObjecttypecode, typeCode));

            data.removeIf(x -> !roaList.stream().anyMatch(r -> r.getObjectid().equals(primaryKeyProviderFunction.getPrimaryKey(x))));
        }
    }

    @Override
    public boolean valid(UUID objectId, int objectTypeCode, List<UUID> roleId) {
        if (_currentUser.isAdministrator())
            return true;
        return _roleObjectAccessService.exists(objectId, objectTypeCode, roleId);
    }
}
